xtask\tasks\fmt\house_rules/
crate_name_nodash.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use anyhow::Context;
5use anyhow::anyhow;
6use std::ffi::OsStr;
7use std::path::Path;
8
9pub fn check_crate_name_nodash(path: &Path) -> anyhow::Result<()> {
10    // while it's _theoretically_ possible to support --fix here, adding new
11    // crates is a relatively uncommon operation, so it's probably not worth the
12    // effort of automating it...
13
14    if path.file_name() != Some(OsStr::new("Cargo.toml")) {
15        return Ok(());
16    }
17
18    let contents = fs_err::read_to_string(path)?;
19    let parsed = contents.parse::<toml_edit::DocumentMut>()?;
20
21    let package_name = match parsed
22        .as_table()
23        .get("package")
24        .and_then(|p| p.get("name"))
25        .and_then(|n| n.as_str())
26    {
27        Some(name) => name,
28        None => return Ok(()), // Workspace root toml
29    };
30
31    if let Some(metadata) = parsed
32        .get("package")
33        .and_then(|x| x.get("metadata"))
34        .and_then(|x| x.get("xtask"))
35        .and_then(|x| x.get("house-rules"))
36    {
37        let props = metadata.as_table().context("invalid metadata format")?;
38        for (k, v) in props.iter() {
39            if k == "allow-dash-in-name" {
40                let is_bin = v
41                    .as_bool()
42                    .context("invalid type for allow-dash-in-name (must be bool)")?;
43                if is_bin {
44                    return Ok(());
45                }
46            }
47        }
48    }
49
50    let bad_package_name = package_name.contains('-');
51    let bad_package_path = {
52        if let Some(parent_path) = path.parent() {
53            parent_path
54                .file_name()
55                .unwrap_or_default()
56                .to_string_lossy()
57                .contains('-')
58        } else {
59            false
60        }
61    };
62
63    let msg = match (bad_package_name, bad_package_path) {
64        (true, true) => "crate name + folder cannot contain '-' char",
65        (true, false) => "crate name cannot contain '-' char",
66        (false, true) => "crate folder cannot contain '-' char",
67        _ => return Ok(()),
68    };
69
70    Err(anyhow!(
71        "{}: name={} folder={}",
72        msg,
73        package_name,
74        path.parent().unwrap_or_else(|| Path::new("")).display()
75    ))
76}